%    Copyright (C) 2001, 2002 Aladdin Enterprises.  All rights reserved.
% 
% This software is provided AS-IS with no warranty, either express or
% implied.
% 
% This software is distributed under license and may not be copied,
% modified or distributed except as expressly authorized under the terms
% of the license contained in the file LICENSE in this distribution.
% 
% For more information about licensing, please refer to
% http://www.ghostscript.com/licensing/. For information on
% commercial licensing, go to http://www.artifex.com/licensing/ or
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
% San Rafael, CA  94903, U.S.A., +1(415)492-9861.

% $Id: gs_devn.ps,v 1.3 2002/11/13 20:23:10 alexcher Exp $
% DeviceN color space method dictionary; this depends on gs_sepr.ps


% verify that DeviceN and Separation color spaces are supported
/.setdevicenspace where
  {
    pop
    /.setseparationspace where
      { pop //false }
      { //true }
    ifelse
  }
  { //true }
ifelse
  { currentfile closefile }
if

.currentglobal true .setglobal
.cspace_util begin


%
%   <c1> ... <cm>  <array>   apply_devn_tint_xform   <c1>' ... <cn>'  <array>
%
% Apply the tint transformation for the DeviceN color intensity values.
/apply_devn_tint_xform
  {
    dup 1 get length 1 add exch
    mark 2 index 2 add 2 roll
    index 3 get exec
    counttomark 2 add -2 roll pop
  }
bind def



colorspacedict
/DeviceN
  mark
    /cs_potential_indexed_base true
    /cs_potential_pattern_base true
    /cs_potential_alternate false
    /cs_potential_icc_alternate false
    /cs_get_ncomps { 1 get length } bind
    /cs_get_range { 1 get length [ exch { 0 1 } repeat ] } bind
    /cs_get_default_color { 1 get length { 1 } repeat } bind

    /cs_get_currentgray
      { //apply_devn_tint_xform exec 2 get //.cs_get_currentgray exec }
    bind
    /cs_get_currentrgb
      { //apply_devn_tint_xform exec 2 get //.cs_get_currentrgb exec }
    bind
    /cs_get_currentcmyk
      { //apply_devn_tint_xform exec 2 get //.cs_get_currentcmyk exec }
    bind

    % a lot of validation is done by the cs_validate method
    /cs_validate
      {
        //check_array exec
        dup 1 get //check_array exec
          {
            type dup /nametype ne exch /stringtype ne and
              //setcspace_typecheck
            if
          }
        forall
        dup 2 get //.cs_validate exec //.cs_potential_alternate exec not
          //setcspace_rangecheck
        if
        dup 3 get //check_array exec xcheck not
          //setcspace_typecheck
        if
      }
    bind

    % substitute the base space if appropriate
    /cs_substitute
      {
        dup 2 get //.cs_substitute exec 2 copy eq
          { pop pop dup }
          {
            % retain only the new alternate space
            exch pop

            % build all new structures in local VM
            .currentglobal 3 1 roll //false .setglobal

            % construct a new array and insert the new base color space
            1 index dup length array copy dup 2 4 -1 roll put

            % restore VM mode
            3 -1 roll .setglobal
          }
        ifelse
      }
    bind

    %
    % The Ghostscript interpreter works better when tinttransform procedures
    % are translated into functions. Attempt to do that here.
    %
    /cs_prepare //converttinttransform

    %
    % Install the current color space.
    %
    % The current Ghostscript color space implementation requires that
    % color spaces that provide a base or alternative color space set
    % that base/alternative color space to be the current color space
    % before attempting to set the original color space.
    %
    % Beginning with Acrobat 5, PDF apparently supports 1-component
    % DeviceN color spaces with the single component "All" (the "PDF
    % Reference", 3rd ed., p. 206 still describes this as illegal).
    % We translate such calls to Separation color spaces.
    %
    /cs_install
      {
        % save the current color space
        currentcolorspace

        % set the base color space as the current color space
        1 index 2 get //forcesetcolorspace

        % set the indexed color space; restore the earlier space on error
        mark 2 index
        dup 1 get dup length 1 eq exch 0 get /All eq and
          {
            dup length array copy
            dup 0 /Separation put
            dup 1 /All put
              { .setseparationspace }
          }
          { { .setdevicenspace } }
        ifelse
        stopped
          { cleartomark setcolorspace stop }
          { pop pop pop }
        ifelse
      }
    bind

    /cs_prepare_color { dup 1 get length //check_num_stack exec pop } bind

    %
    % If a DeviceN color space is not supported in native mode by
    % the current process color model, Adobe implementations will always
    % execute the tint transform procedure when setcolor is invoked.
    % Ghostscript may have turned this transform into a sampled function,
    % and even if this is not the case, will have sampled the transform
    % when the color space is first set. Some applications depend on
    % the Adobe behavior, so we implement it via the cs_complete_setcolor
    % method.
    %
    /cs_complete_setcolor
      {
        .usealternate
          {
            pop currentcolor
            currentcolorspace 3 get exec
            currentcolorspace 2 get
            //clear_setcolor_operands exec
          }
          { pop }
        ifelse
      }
    bind

  .dicttomark
put

end     % .cspace_util
.setglobal
